home *** CD-ROM | disk | FTP | other *** search
/ Programmer Plus 2007 / Programmer-Plus-2007.iso / Programming / XML Utilities / Professional Programmer XSL IDE / Xselerator25.msi / Data.Cab / F40246_iter.xsl < prev    next >
Encoding:
Text File  |  2002-04-08  |  8.8 KB  |  188 lines

  1. <!--
  2. ===========================================================================
  3.  Stylesheet: iter.xsl       General Iteration of a Function                
  4.     Version: 1.0 (2002-03-16)                                              
  5.      Author: Dimitre Novatchev                                             
  6.      Notice: Copyright (c)2002 D.Novatchev  ALL RIGHTS RESERVED.           
  7.              No limitation on use - except this code may not be published, 
  8.              in whole or in part, without prior written consent of the     
  9.              copyright owner.                                              
  10. ===========================================================================-->
  11. <xsl:stylesheet version="1.0" 
  12.  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  13.  xmlns:vendor="http://xml.apache.org/xalan"
  14.  exclude-result-prefixes="xsl vendor">
  15.  
  16. <!--
  17. ===========================================================================
  18.        this implements functional power composition,                       
  19.        that is f(f(...f(x)))))...)                                         
  20.                                                                            
  21.        f composed with itself n - 1 times                                  
  22.                                                                            
  23.        The corresponding Haskell code is:                                  
  24.         > iter :: (Ord a, Num a) => a -> (b -> b) -> b -> b                
  25.         > iter n f                                                         
  26.         >    | n > 0     = f . iter (n-1) f                                
  27.         >    | otherwise = id                                              
  28. ===========================================================================-->
  29. <!--
  30.     Template: iter                                                           
  31.      Purpose: Iterate (compose a function with itself) N times               
  32.   Parameters:-                                                               
  33.     $pTimes - [optional] number of times to iterate                          
  34.     $pFun   - a template reference to the function that's to be iterated     
  35.     $pX     - an initial argument to the function                            
  36.   ========================================================================== -->
  37.   <xsl:template name="iter">
  38.     <xsl:param name="pTimes" select="0"/>
  39.     <xsl:param name="pFun" select="/.."/>
  40.     <xsl:param name="pX" />
  41.     
  42.     <xsl:choose>
  43.       <xsl:when test="$pTimes = 0" >
  44.         <xsl:copy-of select="$pX"/>
  45.       </xsl:when>
  46.       <xsl:when test="$pTimes = 1">
  47.         <xsl:apply-templates select="$pFun">
  48.           <xsl:with-param name="arg1" select="$pX"/>
  49.           </xsl:apply-templates>
  50.       </xsl:when>
  51.       <xsl:when test="$pTimes > 1">
  52.         <xsl:variable name="vHalfTimes" select="floor($pTimes div 2)"/>
  53.         <xsl:variable name="vHalfIters">
  54.           <xsl:call-template name="iter">
  55.             <xsl:with-param name="pTimes" select="$vHalfTimes"/>
  56.             <xsl:with-param name="pFun" select="$pFun"/>
  57.             <xsl:with-param name="pX" select="$pX"/>
  58.           </xsl:call-template>
  59.         </xsl:variable>
  60.           
  61.         <xsl:call-template name="iter">
  62.           <xsl:with-param name="pTimes" select="$pTimes - $vHalfTimes"/>
  63.               <xsl:with-param name="pFun" select="$pFun"/>
  64.               <xsl:with-param name="pX" select="vendor:node-set($vHalfIters)"/>
  65.         </xsl:call-template>
  66.       </xsl:when>
  67.       <xsl:otherwise>
  68.         <xsl:message>[iter]Error: the $pTimes argument must be
  69.                       a positive integer or 0.
  70.         </xsl:message>
  71.       </xsl:otherwise>
  72.     </xsl:choose>
  73.     
  74.   </xsl:template>
  75.  
  76. <!--
  77. ===========================================================================
  78.        This is a variation of the iter function.                           
  79.        Iterations are performed only while the predicate p                 
  80.        is true on the argument of the iteration                            
  81. ===========================================================================-->
  82. <!--
  83.     Template: iterUntil                                                      
  84.      Purpose: Iterate (compose a function with itself)                       
  85.               until a condition is satisfied                                 
  86.   Parameters:-                                                               
  87.     $pCond  - a template reference to a predicate that tests                 
  88.               the iteration stop-condition. Returns 0 or 1                   
  89.     $pFun   - a template reference to the function that's to be iterated     
  90.     $arg1   - an initial argument to the function                            
  91.   ========================================================================== -->
  92.    <xsl:template name="iterUntil">
  93.     <xsl:param name="pCond" select="/.."/>
  94.     <xsl:param name="pFun" select="/.."/>
  95.     <xsl:param name="arg1" select="/.."/>
  96.     
  97.     <xsl:variable name="vCond">
  98.       <xsl:apply-templates select="$pCond">
  99.         <xsl:with-param name="arg1" select="$arg1"/>
  100.       </xsl:apply-templates>
  101.     </xsl:variable>
  102.     
  103.     <xsl:choose>
  104.       <xsl:when test="$vCond = 1" >
  105.         <xsl:copy-of select="$arg1"/>
  106.       </xsl:when>
  107.       <xsl:otherwise>
  108.         <xsl:variable name="vrtfFunResult">
  109.             <xsl:apply-templates select="$pFun">
  110.               <xsl:with-param name="arg1" select="$arg1"/>
  111.             </xsl:apply-templates>
  112.         </xsl:variable>
  113.         
  114.         <xsl:call-template name="iterUntil">
  115.           <xsl:with-param name="pCond" select="$pCond"/>
  116.           <xsl:with-param name="pFun" select="$pFun"/>
  117.           <xsl:with-param name="arg1"
  118.                  select="vendor:node-set($vrtfFunResult)/node()"/>
  119.         </xsl:call-template>
  120.       </xsl:otherwise>
  121.     </xsl:choose>
  122.   </xsl:template>
  123.   
  124. <!--
  125.   This template implements the scanIter function                            
  126.   defined in Haskell as:                                                    
  127.                                                                             
  128.   > scanIter :: (Ord a, Num a) => a -> (b -> b) -> b -> [b]                 
  129.   > scanIter n f x                                                          
  130.   >    | n == 0  = [x]                                                      
  131.   >    | n > 0   = result ++ [f(last result)]                               
  132.   >                  where result = scanIter (n-1) f x                      
  133.   ==========================================================================-->
  134.  
  135.   
  136. <!--
  137.     Template: scanIter                                                      
  138.      Purpose: Iterate (compose a function with itself) N times              
  139.               and produce a list, whose elements are the results            
  140.               from the partial iterations                                   
  141.   Parameters:-                                                              
  142.     $arg1   - the number of times to iterate                                
  143.     $arg2   - a template reference to the function that's to be iterated    
  144.     $arg3   - an initial argument to the function                           
  145.     $arg4   - [optional] name for the elements in the result node-set       
  146.   ==========================================================================-->
  147.   <xsl:template name="scanIter">
  148.     <xsl:param name="arg1"/>               <!-- n -->
  149.     <xsl:param name="arg2" select="/.."/>  <!-- f -->
  150.     <xsl:param name="arg3"/>               <!-- x -->
  151.     <xsl:param name="arg4" select="'el'"/> <!-- elName -->
  152.     
  153.     <xsl:choose>
  154.      <xsl:when test="$arg1 < 0">
  155.        <xsl:message>[scanIter]Error: Negative value for n.</xsl:message>
  156.      </xsl:when>
  157.      <xsl:when test="$arg1 = 0">
  158.        <xsl:element name="{$arg4}">
  159.            <xsl:value-of select="$arg3"/>
  160.        </xsl:element>
  161.      </xsl:when>
  162.      <xsl:otherwise>
  163.        <xsl:variable name="vrtfIterMinus">
  164.          <xsl:call-template name="scanIter">
  165.            <xsl:with-param name="arg1" select="$arg1 - 1"/>
  166.            <xsl:with-param name="arg2" select="$arg2"/>
  167.            <xsl:with-param name="arg3" select="$arg3"/>
  168.            <xsl:with-param name="arg4" select="$arg4"/>
  169.          </xsl:call-template>
  170.        </xsl:variable>
  171.        
  172.        <xsl:variable name="vIterMinus" 
  173.                      select="vendor:node-set($vrtfIterMinus)/*"/>
  174.        
  175.        <xsl:variable name="vrtfLastIter">
  176.          <xsl:element name="{$arg4}">
  177.              <xsl:apply-templates select="$arg2">
  178.                <xsl:with-param name="arg1" select="$vIterMinus[last()]"/>
  179.              </xsl:apply-templates>
  180.          </xsl:element>
  181.        </xsl:variable>
  182.        
  183.          <xsl:copy-of select="$vIterMinus"/>
  184.          <xsl:copy-of select="vendor:node-set($vrtfLastIter)"/>
  185.      </xsl:otherwise>
  186.     </xsl:choose>
  187.   </xsl:template>
  188. </xsl:stylesheet>